package top.codingfly.examples;

import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import top.codingfly.netty.common.NettyHandler;
import top.codingfly.netty.utils.ByteExtUtil;

import java.util.List;

public abstract class CommonHandler extends NettyHandler {

    // length(bit数据长度)+type(int类型)+zipFlag(1字节)+data(byte数组)
    @Override
    public void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception {
        if (in.readableBytes()<8) {
            return;
        }
        in.markReaderIndex();
        byte[] lengthBytes = new byte[4];
        in.readBytes(lengthBytes);
        int length = ByteExtUtil.bytesToInt(lengthBytes);
        if (in.readableBytes() < length) {
            // 数据不足
            in.resetReaderIndex();
            return;
        }
        ProtocolPacket packet = new ProtocolPacket();
        byte[] typeBytes = new byte[4];
        in.readBytes(typeBytes);
        int type = ByteExtUtil.bytesToInt(typeBytes);
        packet.type = type;
        if (length>=4) {
            Byte zipFlag = in.readByte();
            byte[] dataBytes = new byte[length - 4 - 1];
            in.readBytes(dataBytes);
            if (zipFlag==1) {
                dataBytes = ZipUtils.uncompress(dataBytes);
            }
            packet.dataBytes = dataBytes;
        }
        out.add(packet);
    }

    @Override
    public <T> void encode(ChannelHandlerContext ctx, T msg, ByteBuf out) throws Exception {
        if (msg==null) {
            return;
        }
        ProtocolPacket packet = (ProtocolPacket) msg;
        int length = 4; // type(占4个字节) + zipFlat(占1个字节) + bytes(所占的字节)
        byte[] writeDataBytes = null;
        Byte zipFlag = null;
        if (packet.dataBytes!=null) {
            // 大于512字节要压缩
            zipFlag = packet.dataBytes.length>512? (byte) 1:(byte) 0;
            if (zipFlag==1) {
                writeDataBytes = ZipUtils.compress(packet.dataBytes);
            } else {
                writeDataBytes = packet.dataBytes;
            }
            length = length + 1 + writeDataBytes.length; // 压缩标志位也占了一个字节
        }
        out.writeBytes(ByteExtUtil.intToBytes(length));
        out.writeBytes(ByteExtUtil.intToBytes(packet.type));
        if (writeDataBytes!=null) {
            out.writeByte(zipFlag);
            out.writeBytes(writeDataBytes);
        }
    }
}
